<script setup>
import { ref, reactive, onMounted, computed, nextTick, h } from 'vue'
import {
    DeleteOutlined,
    PlusOutlined,
    CloudUploadOutlined,
    PauseCircleOutlined,
    PlayCircleOutlined,
    CheckOutlined,
    EyeOutlined,
    UnorderedListOutlined
} from '@ant-design/icons-vue'

import request from "@/common/utils/request";

// 富文本 - 公用数字人形象的富文本
import editor from './editor/index.vue'
const editorRef = ref([])
// 选择数字人弹窗
import selectHumanDialog from '@/views/shotstack/digitalHuman/AIdigitalHumanMassProduction/Components/selectHumanDialog.vue'
const selectHumanDialogRef = ref()
// 仓库
import { useStore } from "vuex";
const store = useStore();

import utils from '@/common/utils/utils.js'

// 充值弹窗
import vipModal from '@/socialMedia/Vip/vipModal.vue'
const vipModalRef = ref(null)
// 充值弹窗开关
const vipVisible = ref(false)

// 预览视频
import previewVideo from '@/views/shotstack/components/dialogComponent/previewVideo.vue'
const previewVideoRef = ref()

// loading 遮罩
import loadingMask from '@/components/loadingMask/index.vue'
const loadingMaskRef = ref()
const loadingText = ref('')
const loading = ref(false)

// loading 弹窗
import syncDialog from './Components/syncDialog.vue'
const syncDialogRef = ref()

// 音色组件
import AudioSelection from "@/views/shotstack/MixedCutPlatforms/mixedCutCreat/components/Component/AudioSelection.vue";

// 素材库
import ChooseMaterial from "@/views/shotstack/EditingCenter/modules/bottomSet/components/chooseMaterial.vue";

// 合成记录列表组件
import HumanList from '@/views/shotstack/digitalHuman/AIdigitalHumanMassProduction/Components/HumanList.vue'
const HumanListRef = ref()

// 文案仿写
import TextImitationDialog from "@/views/shotstack/components/TextImitationDialog/index.vue";
let TextImitationDialogRef = ref(null);
// 文案库组件
import CopyLibraryModal from "@/components/AddTextModal/CopyLibraryModal.vue";
const CopyLibraryModalRef = ref()

// 批量获取音频
import {getAudioList, scrollToBottom, whetherToUp} from '@/common/utils/atherUtils.js'

import {getVoiceConfige} from '@/common/utils/atherUtils.js'
import { nanoid } from 'nanoid'
import { message } from 'ant-design-vue'

const state = reactive({
    // 默认音色
    voiceData: null,
    // 默认音色配置
    voice_config: null,
    // 渲染列表
    aiList: [],

    // 素材库开关
    visible: false,

    // 是否生成字幕 1 生成 0 不生成
    is_subtitles:'0',

    // 头部tap栏位
    topActiveKey: 'creat',
    // 转字幕, 积分消耗提示词
    tips: '',

    // 批量生成 提交按钮loading
    submitLoading:false
})

// 数字人视频 组数上限
const maxNum = 10

// 文本字数最小值
const minTextLen = 20

// 进行编辑的 --id
const editItemId = ref('')

// 默认音频配置 voice_type == 1
const voice_config = computed(() => {
  return store.state.videoMixCut.voice_config;
});

// 推荐的默认音频配置 voice_type == 2
const volcengine_config = computed(() => {
  return store.state.videoMixCut.volcengine_config;
});

// 获取渲染列表的一组数据
const getItemData = (voice_type) => {
    console.log(voice_type,' 音色类型');
    
    const id = nanoid()
    const voiceConfig = voice_type == 2
        ? JSON.parse(JSON.stringify(volcengine_config.value))
        : JSON.parse(JSON.stringify(voice_config.value))
        
    return {
        id,
        editName: false,
        name:`数字人视频${state.aiList.length + 1}`,
        // 数字人信息
        ai_human_data: null,
        // 音色对应的音频配置:最大值 最小值 默认值
        voice_config:voiceConfig,
        // 默认音色配置
        voiceData: JSON.parse(JSON.stringify(state.voiceData)),
        // 合成用的 音频链接
        audio_url: '',
        // 文本转语音 音频链接
        text_audio_url: '',
        // 音频模式, 素材库选择的素材
        material:null,
        
        // 使用的是文本 还是 音频内容 text - audio
        activeKey: 'text',

        // 音频播放状态
        voiceState: false,

        // 是否生成字幕
        is_subtitles: '0',

        // 音频驱动 时长
        audio_duration: 0,
        // 文本驱动 时长
        text_duration: 0,
        // 不进行四舍五入的 文本时长
        text_base_duration: 0,
        // 不进行四舍五入的 音频时长
        audio_base_duration: 0,
        // 扩写 改写 loading
        AISpinging:false

    }
}

// 选择数字人弹窗
const changeAIHuman = (item) => {
    editItemId.value = item.id
    selectHumanDialogRef.value?.open()
}

// 弹窗选择数字人回调
const selectHuman = (item) => {
    console.log(item, '选择数字人回调');
    const editItem = state.aiList.find(ele => ele.id == editItemId.value)
    if (!!editItem) {
        editItem.ai_human_data = item
    }
}

// 音色选择
const audioSelection = ref(null);

const voiceSelector = (item) => {
    console.log(item?.voiceData,'voiceData');
    
    editItemId.value = item.id
  audioSelection.value.showModal();
};

// 选择 音色回调
const resetDataChange = (data) => {
    const { voiceDataItem, config } = data || {};
    console.log(Object.keys(voiceDataItem).length,'有没有选择音色');
    
    if(!Object.keys(voiceDataItem).length) return
    console.log(data, "选择的音色");
    const editItem = state.aiList.find(ele => ele.id == editItemId.value)
    if (!!editItem) {
        const voiceVal = getVoiceConfigVal(voiceDataItem.voice_type)
        Object.assign(voiceDataItem,voiceVal)
        voiceDataItem.volume
        editItem.voiceData = voiceDataItem
        
        // 音色的配置
        const voiceConfig = voiceDataItem.voice_type == 2
        ? JSON.parse(JSON.stringify(volcengine_config.value))
        : JSON.parse(JSON.stringify(voice_config.value))
        editItem.voice_config = voiceConfig

        console.log(editItem.voiceData, '赋值完基础配置参数的音色');
        // 清空此项的 缓存音频
        editItem.text_duration = 0
        editItem.text_base_duration = 0
        editItem.text_audio_url = ''
    }
};

// 获取基础的 声音配置值
const getVoiceConfigVal = (voice_type) => {
    console.log(voice_config.value, 'voice_configvoice_configvoice_config');
    let data

    if (voice_type == 2) {
        data = {
            speed: volcengine_config.value.speed.default,
            emotion_intensity: '',
            volume: ''
        }
    } else {
        data = {
            speed: voice_config.value.speed.default,
            emotion_intensity: voice_config.value.pitch.default,
            volume: voice_config.value.volume.default
        }
    }
    return data
}

// 新增场景
const addNewItem = () => {
    if(state.aiList.length >= maxNum) {
        message.error(`最多${maxNum}个场景`)
        return
    }
    const item = getItemData(state.voiceData.voice_type)
    state.aiList.push(item)

    nextTick(() => {
        // 滚动到底部
        scrollToBottom('#content_left_list_scroll_box')
    })
}

 // 获取初始数据
const getVoiceConfigeFn = async() => {
    const params = await getVoiceConfige()
    const {data, voice_config} = params
    state.voiceData = data
    state.voice_config = voice_config
    const item = getItemData(state.voiceData.voice_type)
    console.log(item,'item的值');
    console.log(volcengine_config,'volcengine_config');
    state.aiList.push(item)
}

// 删除某项数据
const delItem = (index) => {
    if(index == 0 && state.aiList.length <= 1) return
    state.aiList.splice(index, 1)
}

// 打开素材库
const selectAudio = (item) => {
    editItemId.value = item.id
    state.visible = true
}

// 素材库选择音频回调
const closeChooseMaterial = (data) => {
  console.log(data, "素材");
    if (data) {
    const editItem = state.aiList.find(ele => ele.id == editItemId.value)
    if (!!editItem) {
        editItem.material = data
        let duration = Math.ceil(data.material_duration / 1000);
        duration = Math.max(duration, 1);
        editItem.audio_duration = Number(duration)
        // 存放原始时长
        editItem.audio_base_duration = Number(data.material_duration / 1000)
        editItem.audio_url = data.material_url;
        console.log(editItem,'存放完参数后');
    }
  }
  state.visible = false;
};

// 音频模式, 删除选择的音频
const delVoice = (index) => {
    state.aiList[index].material = null
    state.aiList[index].audio_url = ''
}

// 播放音频
const playVoice = (item) => {
    const dom = document.getElementById(`audio_AIdigitalHumanMassProduction_${item.id}`)
  if (dom) {
    if (dom.paused) {
      dom.play(); // 如果音频是暂停的，则播放
      item.voiceState = true;
    } else {
      dom.pause(); // 如果音频正在播放，则暂停
      item.voiceState = false;
    }
  }
};

// 校验数据
const validateData = async () => {

return new Promise((resolve, reject) => {
    // 检测每个数据都要有数字人
    const hasHuman = state.aiList.every((item, index) => item.ai_human_data)

    // 触发富文本的检测校验
    state.aiList.forEach((ele, index) => {
        if (ele.activeKey == 'text') {
            editorRef.value[index]?.testTextLength()
        }
    })

    if (!hasHuman) {
        message.error('请选择数字人!')
        reject()
        return
    }

    console.log(state.aiList, 'state.aiList');

        // 赋值富文本内容, 判断清空音频
        state.aiList.forEach((item, index) => {
        if (item.activeKey == 'text') {
            // 获取此项的富文本内容
            const text = editorRef.value[index]?.getContent()
            console.log(text, '每一项富文本的内容');
            item.textData = text?.textData
            // 如果此项的内容 和上一次不一样, 清空音频
            if (item?.textData?.text && item.textData.text != text?.textData?.text) {
                item.text_audio_url = ''
            }
        }
    })

    // 检测每个数据 - 文本内容 或者 音频内容 都要有内容
    const hasVoice = state.aiList.every((item, index) => {
        if (item.activeKey == 'text') {
            return !!item.textData?.text && !!item.textData?.text?.trim()
        } else {
            return !!item.material
        }
    })

    console.log(hasVoice, '是否每项都符合条件')
    if (!hasVoice) {
        message.error('请输入文本内容或者选择音频!')
        reject()
        return
        }

        resolve()
})

}

const configeChange = (item) => {
    console.log(item, '配置改变');
    // 配置改变, 清空本项的音频
    item.audio_url = ''
}

// 获取数字人 消耗提示
const getHumanConfig = (number) => {
  // 判断 普通 / 高级 模式
  // if (modelRef.modal == "ov4_7") {
  //   usernumbers = state.usenumber * 2;
  // } else {
  //   usernumbers = state.usenumber;
    // }

  let res
    return new Promise(async (resolve, reject) => {      
        const is_subtitles_num = state.aiList.filter(ele => ele.is_subtitles == 1).length
        try {
         res = await request.get("/work_ai", "/digital/human/config/moreGetConfig", {
             number,
             is_subtitles_num
        });
            if (res?.usable != 1) {
              // 充值打开弹窗
              throw new Error('点数不够');
            }
        //  res = await utils.humanConfigGet({ number })
        // 查询积分, 积分不足则走不到这一步
        // 获取积分消耗提示内容
        const content = utils.useText(res)
        try {
          // 确认消耗
          await utils.kd({ content,res })
          resolve(res)
        } catch (error) {
          reject(error)
        }
        } catch (error) {
        reject(error)
          // 询问是否充值
          if (res) {
            const content = utils.useText(res, '点数不足，请先充值')
              await whetherToUp({ content,res })
              vipVisible.value = true
              vipModalRef.value && vipModalRef.value.openBuyVisible()
          }
        
      }
    })
};

// 关闭loading
const closeLoading = () => {
    loading.value = false
    state.submitLoading = false
    syncDialogRef.value?.close()
}

const viewTask = () => {
    // alert('点了')
    state.topActiveKey = 'preview'
    clearData()
    message.destroy()
}

// 批量生成
const startCreats = async () => {
    // console.log(state.aiList, '批量生成');


    await validateData()

    // 开启按钮loading
    state.submitLoading = true


    // 批量获取音频
    const textList = state.aiList.filter(ele => ele.activeKey == 'text' && !ele.text_audio_url).map(ele => {
        return {
            // 获取音频的文案
            text: [{
                text: ele.textData.text,
                id: ele.id
            }],
            // 用于获取完音频 回显的id
            id: ele.id,
            // 音频配置
            voiceConfige: {
                category: ele.voiceData?.category ?? '',
                emotion_category: ele.voiceData?.emotion_category ?? '',
                emotion_intensity: ele.voiceData?.emotion_intensity?? '',
                speed: ele.voiceData?.speed?? '',
                volume: ele.voiceData?.volume ?? '',
                id: ele.voiceData?.id ?? '',
                timbre_id: ele.voiceData?.timbre_id?? '',
            }
        }
    })

    if (textList.length) {

        
    // 判断 是否每项的文案都大于 20个字
        const wordNumberVerify = textList.every(ele => ele.text[0].text.trim().length >= minTextLen)
            
        if(!wordNumberVerify) {
            message.error(`文案字数不能小于${minTextLen}个字`)
            state.submitLoading = false
            return 
        }

    const allText = textList.map(ele => ele.text[0].text).join('')
        console.log(allText, '所有的文本');

        
    // 提示积分消耗
        const number = allText.length
      let res
      try {

        res = await request.get(
        "/work_ai",
        "/user/shotstack/text_to_speech/config/get",{number}
        );
        if (res?.usable != 1) {
        // 充值打开弹窗
            throw new Error('点数不够');
        }

        // 查询积分, 积分不足则走不到这一步
        // 获取积分消耗提示内容
        const content = utils.useText(res)
        try {
          // 确认消耗
          await utils.kd({ content,res })
        } catch (error) {
            closeLoading()
          return
          }
      } catch (error) {
        // 打开充值, 接着打开点数购买
          closeLoading()
          if (res) {
            const content = utils.useText(res, '点数不足，请先充值')
              await whetherToUp({ content,res })
              vipVisible.value = true
              vipModalRef.value && vipModalRef.value.openBuyVisible()
          }
          return
        }

        // 开启遮罩
        loadingText.value = '视频生成中, 请稍后...'
        // loading.value = true

        syncDialogRef.value?.open({
            content:'语音获取中, 请稍后...',
            subTitle:'正在文本转语音...',
            showClose: false,
        })

        loadingText.value = '音频获取中, 请稍后...'

        console.log(textList, '即将获取音频的项');
        try {
        const resArr =  await getAudioList(textList)
            console.log(resArr, '获取完音频的结果');
            // 关闭一下弹窗
            syncDialogRef.value?.close()
        resArr.forEach(item => {
            const find = state.aiList.find(ele => ele.id == item.id)
            // 存放时长, 向上取整 + 至少为1
            let duration = Math.ceil(item.duration);
            duration = Math.max(duration, 1);
            if (!!find) {
                find.text_audio_url = item.audio
                find.text_duration = Number(duration)
                // 存放原始时长
                find.text_base_duration = Number(item.duration)
            }
        })
        loadingText.value = '视频生成中, 请稍后...'
        } catch (error) {
            closeLoading()
            return
        }      
    }

    // 提交参数
    console.log(state.aiList, 'aiList 提交参数');
    // 获取唯一id
    const res = await request.get("/work_ai", "/user/platform/uniqueId")
    const uniqueId = res.uniqueId

   const human_video_data = state.aiList.map((item, index) => {
        return  {
                    name: item.name,
                    audio_url:  item.activeKey == 'text' ? item.text_audio_url  : item.audio_url,
                    type: 'ov4',
                    line_type: '7',
                    human_id: item.ai_human_data?.id,
                    is_subtitles: item.is_subtitles,
                }
    })

    const submitData = {
        uniqueId,
        human_video_data,
        // 0 异步, 1 同步
        is_sync:0
    }

    console.log(submitData, '最后提交的数据');

    // 计算每一项音频的时长是否 大于5秒 小于3分钟
    const isDuration = state.aiList.every(item => {
        if (item.activeKey == 'text') {
            return item.text_base_duration >= 5 && item.text_base_duration <= 180
        } else {
            return item.audio_base_duration >= 5 && item.audio_base_duration <= 180
        }
    })
    if (!isDuration) {
        closeLoading()
        message.error('音频时长必须大于5秒, 小于3分钟!')
        return
    }
    // 计算总时长
    const allDuration = state.aiList.reduce((total, item) => {
        if (item.activeKey == 'text') {
            return total + item.text_duration
        } else {
            return total + item.audio_duration
        }
    }, 0)

    console.log(allDuration,'生成数字人视频的总时长');
    
    // 合成消耗提示
    try {
        await getHumanConfig(allDuration)
        // 打开提示弹窗
        syncDialogRef.value?.open({
            content: `合成进度请在合成记录中查看`,
            subTitle:`正在批量合成${state.aiList.length}个数字人视频`,
            showClose: true,
        })
    } catch (error) {
        closeLoading()
        return
    }

    // 发起合成
    try {
        const result = await request.post("/work_ai", "/digital/human/video/moreAdd", submitData)
        console.log(result, '批量合成数字人, 结果');
        loading.value = false
        state.submitLoading = false
        // closeLoading()
        if (result?.code && result?.code != 1000) return
    } catch(error) {
        closeLoading()
        message.error('任务提交失败!')
    }
}

// 
const globSczmChange = (val) => {
    console.log(val,'全局变化');
    state.aiList.forEach(item => {
        item.is_subtitles = val 
    })
}

const itemSczmChange = () => {
    console.log(state.aiList,'每一个都开启了嘛');
    const isAll = state.aiList.every(ele => ele.is_subtitles == '1')
    state.is_subtitles = isAll ? '1' : '0'
}

// 生成字幕积分消耗提示词
const getGenerateSubtitlesConfig = async () => {
  const res = await request.get(
      "/work_ai",
      "/human/video/aiAsr/point/get"
    );
  console.log(res, "获取配置");
  // 业务名称
  const name = res?.numberInfo?.name
  // 积分别名
  const pointName = res?.pointInfo?.name 
  // 业务消耗单位
  const unit = res?.numberInfo?.unit
  // 积分消耗单位
  const pointUnit = res?.pointInfo?.unit
  // 积分消耗数量
  const pointNumber = res?.pointInfo?.consumes
    const tips = `${name}消耗${pointNumber}${pointUnit}${pointName}/${unit}`
    state.tips = tips
  return tips
}

// 清空创建列表数据
const clearData = () => {
    state.aiList = []  
    addNewItem()
}


// 修改名称逻辑
const copyName = ref('')
const editNameStart = (item) => {
    editItemId.value = item.id
    copyName.value = item.name
    item.editName = true

    nextTick(() => {
        const dom = document.getElementById(`inputName_${item.id}`)
        dom?.focus()
    })
}

// 数字人视频修改名称
const changeNameBlur = (item) => {
    if(!item.name.trim() && !!copyName.value.trim()) {
        item.name = copyName.value
    }
    item.editName = false
    copyName.value = ''
}

//查看视频
const toviewVideo = (item) => {
    previewVideoRef.value.open(item.ai_human_data?.video_url)
};

const tabsChange = (key) => {
    if (key == 'creat') {
        // 同步一下 勾选信息
        itemSczmChange()
    }
}

// 文案库导入
const importingLibrary = (item) => {
    editItemId.value = item.id
    CopyLibraryModalRef.value?.showModal();
};

// 文案库导入成功回调
const audioLItemImportSuccess = (data) => {
  if (data.length) {
    const text = data[0].material_content
      // 赋值富文本
      const index = state.aiList.findIndex(ele => ele.id == editItemId.value)
    if(index != -1) {
      editorRef.value?.[index]?.setContent(text)
    }
    
  }
};

// 文案仿写导入
const importingTextImiton = (item) => {
    editItemId.value = item.id
    TextImitationDialogRef.value?.showModal();
};

// 获取文案仿写文本
const getTextArr = (list) => {
  const text = list[0]?.content
    // 赋值富文本
    const index = state.aiList.findIndex(ele => ele.id == editItemId.value)
    if(index != -1) {
        editorRef.value?.[index]?.setContent(text)
    }
  TextImitationDialogRef.value.closeModal()
}

// AI改写
const handleAIRequest = async (param) => {
    const { clickType, index } = param

    const item = state.aiList[index]
    if (!item) {
      return 
    }

    // 获取此项富文本的内容
    const textContent = editorRef.value?.[index]?.getContent()
    const text = textContent?.textData?.text?.trim() || ''
  if (!text) {
    return message.error("请输入内容");
  }
  try {
    // 查看用户的点数是否足够消耗
    await utils.aiTextGet()
    try {
      // 消耗规则
      const rule = await utils.consumptionPointRule()
      // 获取提示
      const content = utils.ruleTips({ res: rule, key: "ai_text_point" })
      // 弹出提示
      await utils.md({ content })
      // 弹窗确认消耗
    } catch (error) {
      return
    }
  } catch (error) {
    // 打开充值, 接着打开点数购买
    vipVisible.value = true
    vipModalRef.value && vipModalRef.value.openBuyVisible()
    return
  }

  const params = {
    // 0-扩写AIExpand 1-改写AIRewriting
    is_text_rewrite: clickType == "AIRewriting" ? 1 : 0,
    ai_keyword_id: "",
    ai_keyword_group_id: "",
    content: text,
    ai_type: "desc", 
    platform: "", 
  };
   item.AISpinging = true;

     try {
        const successRes = await request.post(
          "work_ai",
          "/user/filmrelease/ai/generate_title",
          params
        );

        if (!successRes || !successRes.result) {
          item.AISpinging = false;
          return message.error("AI生成失败，状态id丢失");
        }

        const timerId = setInterval(async () => {
          try {
            const statusRes = await request.get(
              "/work_ai",
              "/user/filmrelease/ai/generate_title/status",
              { task_id: successRes.result }
            );
            if (
              statusRes.result.status === "success" ||
              statusRes.result.status === "error"
            ) {

              if (statusRes.result.data.length) {
              // const originalString = statusRes.result.data[0]; 
              // state.text = originalString.substring(originalString.indexOf('\n') + 1);
                  const text = statusRes.result.data[0]
                  editorRef.value?.[index]?.setContent(text)
                  
                // updateEditor({text})
              }
              clearInterval(timerId);
              item.AISpinging = false;
            }
          } catch (statusErr) {
            item.AISpinging = false;
            clearInterval(timerId);
          }
        }, 1000);


      } catch (errorRes) {
        console.log(errorRes);
      }

}

const timerOver = () => {
    syncDialogRef.value?.close()
    viewTask()
}

onMounted(() => {
    // 获取配音基础配置信息
    getVoiceConfigeFn()
    // 获取转字幕提示词
    getGenerateSubtitlesConfig()

    // nextTick(() => {
    //     syncDialogRef.value?.open({
    //         content: `合成进度请在合成记录中查看`,
    //         subTitle:`正在批量合成${state.aiList.length}个数字人视频`,
    //         showClose: true,
    //     })
    // })
})

</script>

<template>
    <div class="AIdigitalHumanMassProduction">
        <div class="content_left">
            <div class="content_left_list_box">
                <div class="top_controls">

            <a-tabs v-model:activeKey="state.topActiveKey" @change="tabsChange">
                <a-tab-pane key="creat">
                    <template #tab>
                        <a-row>
                            <a-col>
                            <play-circle-outlined style="font-size: 20px" />
                            </a-col>
                            <a-col> 生成视频 </a-col>
                        </a-row>
                    </template>
                </a-tab-pane>
                <a-tab-pane key="preview" force-render>
                    <template #tab>
                        <a-row>
                            <a-col>
                            <unordered-list-outlined style="font-size: 20px" />
                            </a-col>
                            <a-col> 合成记录 </a-col>
                        </a-row>
                        </template>
                </a-tab-pane>
            </a-tabs>

            <div class="top_controls_right" v-if="state.topActiveKey == 'creat'">
                <a-tooltip placement="top">
                    <template #title>
                    <span>{{state.tips}}</span>
                    </template>
                    <!-- <a-button>Top</a-button> -->
                    <div>
                    <span style="margin-right: 5px;">一键开启生成字幕</span>
                    <a-switch checkedValue="1" unCheckedValue="0" v-model:checked="state.is_subtitles"  @change="globSczmChange"/>
                </div>
                </a-tooltip>

                <a-button type="primary" @click="startCreats" :loading="state.submitLoading">提交任务</a-button>
            </div>
                </div>

                <template v-if="state.topActiveKey == 'creat'">
                    <div id="content_left_list_scroll_box" class="content_left_list_scroll_box">
                        <div class="content_left_list_item" v-for="(item, index) in state.aiList" :key="item.id">
                                <a-spin :spinning="item.AISpinging"> 
                                <div class="cart_top">
                                    <div class="cart_top_left">
                                        <div class="cart_title">
                                            <template v-if="item.editName">
                                                <a-input :id="`inputName_${item.id}`" @pressEnter="changeNameBlur(item)" @blur="changeNameBlur(item)" v-model:value="item.name" placeholder="请输入视频名称" >
                                                    <template #suffix>
                                                        <CheckOutlined  @click="changeNameBlur(item)"/>
                                                    </template>
                                                </a-input>
                                            </template>
                                            <template v-else>
                                                <span @click="editNameStart(item)">{{ item.name }}</span>
                                            </template>
                                        </div>
                                        <div class="cart_top_left_right">
                                            <div class="human_audio_type" 
                                            @click="item.activeKey = 'text'"
                                            :class="{'active_cls': item.activeKey == 'text'}">文本驱动</div>
                                            <div class="human_audio_type" 
                                            @click="item.activeKey = 'audio'"
                                            :class="{'active_cls': item.activeKey == 'audio'}">音频驱动</div>
                                    </div>
                                </div>
            
                                <div class="cart_top_right">
                                    <a-tooltip placement="topRight" :autoAdjustOverflow="false" :getPopupContainer="triggerNode => {
                                        return triggerNode.closest('.ss-layout-content');
                                    }">
                                        <template #title>
                                        <span>{{state.tips}}</span>
                                        </template>
                                    <div style="display: flex; align-items: center;">
                                        <span style="margin-right: 5px;">生成字幕</span>
                                        <a-switch checkedValue="1" unCheckedValue="0" v-model:checked="item.is_subtitles"  @change="itemSczmChange"/>
                                    </div>
                    </a-tooltip>
                                    <a-button @click="delItem(index)" type="link" danger v-if="state.aiList.length > 1">
                                        <DeleteOutlined/>
                                        删除
                                    </a-button>
                                </div>
                                </div>
                                <div class="cart_content">
                                    <div class="cart_content_left">
                                        <template v-if="item?.ai_human_data">
                                            <div class="diahuman_video">
                                                <EyeOutlined @click="toviewVideo(item)" class="EyeOutlined"></EyeOutlined>

                                                <!-- 优先展示图片 -->
                                                <img v-if="item.ai_human_data?.url_image" :src="item.ai_human_data?.url_image" alt="">
                                                <video v-else :src="item.ai_human_data?.video_url"></video>
                                            </div>
                                        </template>
                                        <div class="add_ai_human" v-else @click="changeAIHuman(item)">
                                            <PlusOutlined class="add_icon"></PlusOutlined>
                                            <span class="add_tips">
                                                选择形象
                                            </span>
                                        </div>
            
                                        <div v-show="item?.ai_human_data" class="change_aihuman" @click="changeAIHuman(item)">更换数字人</div>
                                    </div>
                                    <div class="cart_content_center">
            
                                        <div v-show="item.activeKey == 'text'">
                                        <div class="text_controls">
                                            <a-button type="link" @click.stop="importingLibrary(item)"  >文案库导入</a-button>
                                            <a-button type="link"  @click.stop="importingTextImiton(item)">文案仿写</a-button>
                                            <a-button type="link" @click.stop="handleAIRequest({
                                                clickType: 'AIExpand',
                                                index,
                                                })"   >
                                            <cu-icon style="" type="icon-iconkuoxie"></cu-icon>AI扩写</a-button>
                                            <a-button type="link" 
                                            @click.stop="handleAIRequest({
                                                clickType: 'AIRewriting',
                                                index,
                                                })">
                                            <cu-icon style="" type="icon-AIgaixie"></cu-icon>
                                            AI改写</a-button>
                                        </div>
                                            <!-- 富文本 -->
                                            <editor :ref="(el) => editorRef[index] = el" :minTextLen="minTextLen"></editor>
                                        </div>  
                                        
                                        <!-- 音频内容 -->
                                        <div class="audio_type_content" v-if="item.activeKey == 'audio'">
                                        <div v-if="!item?.material" class="select_voice_style select_voice" @click="selectAudio(item)">
                                        <CloudUploadOutlined class="FolderOutlined"></CloudUploadOutlined>
                                        <span class="select_tips">点击此处选择或上传您的音频文件</span>
                                        </div>
                                        <div class="select_voice_style have_voice" v-else>
                                            <DeleteOutlined class="del_icon" @click="delVoice(index)"></DeleteOutlined>
                                            <!-- 音频暂停状态 -->
                                            <PauseCircleOutlined class="voice_icon" v-if="item.voiceState" @click="playVoice(item)">
                                            </PauseCircleOutlined>
                                            <!-- 音频播放状态 -->
                                            <PlayCircleOutlined v-else @click="playVoice(item)" class="voice_icon">
                                            </PlayCircleOutlined>
                                            <audio ref="voice" :id="`audio_AIdigitalHumanMassProduction_${item.id}`" @ended="endedChange" @play="onPlayChange" @pause="onPauseChange"
                                                :src="item.audio_url" controls></audio>
                                            </div>
                                        </div>
            
                                    </div>
                                    <div class="cart_content_right" v-if="item.activeKey == 'text'">
                                        <div class="cart_content_voice">
                                            <img :src="item?.voiceData?.img" alt="">
                                            <div class="voice_name">
                                                <span>{{item.voiceData?.name}}</span>
                                            </div>
                                            <a-button size="small" type="primary" @click="voiceSelector(item)">更换</a-button>
                                        </div>
            
                                        <!-- 分割线 -->
                                        <div style="margin: 3px 0; background-color: rgb(229 229 229); height: 0.5px;"></div>
            
                                        <div class="cart_content_voice_config">
                                            <div class="voice_config_item" v-if="item.voiceData.voice_type != 2">
                                                <p class="config_subtitle">音量</p>
                                                <div class="slider_box">
                                                <span style="margin-right: 8px">
                                                    {{item.voice_config.volume.min}}
                                                </span>
                                                <a-slider class="slider" :min="item.voice_config.volume.min" :max="item.voice_config.volume.max" id="test"
                                                :step="item.voice_config.volume.separate" v-model:value="item.voiceData.volume" 
                                                @change="configeChange(item)"
                                                />
                                                <span style="margin-right: 8px">
                                                    {{item.voice_config.volume.max}}
                                                </span>
                                                    </div>           
                                            </div>
            
                                            <div class="voice_config_item">
                                                <p class="config_subtitle">语速</p>
                                                <div class="slider_box">
                                                <span style="margin-right: 8px">
                                                    {{item.voice_config.speed.min}}
                                                </span>
                                                <a-slider class="slider" :min="item.voice_config.speed.min" :max="item.voice_config.speed.max"
                                                :step="item.voice_config.speed.separate" v-model:value="item.voiceData.speed" 
                                                @change="configeChange(item)"
                                                />
                                                <span style="margin-right: 8px">
                                                    {{item.voice_config.speed.max}}
                                                </span>
                                                    </div>           
                                            </div>
            
                                            <div class="voice_config_item" v-if="item.voiceData.voice_type != 2">
                                                <p class="config_subtitle">情感</p>
                                                <div class="slider_box">
                                                <span style="margin-right: 8px">
                                                    {{item.voice_config.intensity.min}}
                                                </span>
                                                <a-slider class="slider" :min="item.voice_config.intensity.min" :max="item.voice_config.intensity.max"
                                                :step="item.voice_config.intensity.separate" v-model:value="item.voiceData.emotion_intensity" 
                                                @change="configeChange(item)"
                                                />
                                                <span style="margin-right: 8px">
                                                    {{item.voice_config.intensity.max}}
                                                </span>
                                                    </div>           
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </a-spin>
                            </div>
                        <div class="add_item_box">
                            <a-button class="btn" type="dashed" style="width: 100%; height: 40px;" @click="addNewItem">+新增场景(最多还可继续添加{{ maxNum - state.aiList.length }}个场景)</a-button>
                        </div>
                    </div>
    
                </template>
                         <!-- 预览列表 -->
                         <template v-else>
                    <HumanList ref="HumanListRef"></HumanList>
                </template>
            </div>

   
        </div>
        <!-- <div class="content_right"></div> -->
    </div>

      <!-- loading 遮罩 -->
  <loadingMask ref="loadingMaskRef" :text="loadingText" :zIndex="1001" :loading="loading"></loadingMask>


    <!-- 选择数字人弹窗 -->
    <selectHumanDialog ref="selectHumanDialogRef" @selectHuman="selectHuman"></selectHumanDialog>

    <!-- 选择音色 -->
    <AudioSelection :notMixedCutCreat="true" ref="audioSelection" @resetDataChange="resetDataChange" :isTextarea="false">
    </AudioSelection>

      <!-- 音频选择 -->
  <ChooseMaterial :isClip="true" material_type="audio" :multiple="false" :visible="state.visible"
    @close="closeChooseMaterial" />

      <!-- 充值弹窗 -->
  <vipModal ref="vipModalRef" :visible="vipVisible" @close="vipVisible = false"></vipModal>
    <!-- 视频预览 -->
  <previewVideo ref="previewVideoRef"></previewVideo>

    <!-- 文案仿写组件 -->
    <TextImitationDialog 
    ref="TextImitationDialogRef" 
    :isone_num="true" :isComponents="true"  
    @getTextArr="getTextArr" :TextContent="''"
  ></TextImitationDialog>
    <!-- 文案库 -->
    <CopyLibraryModal ref="CopyLibraryModalRef" @importSuccess="audioLItemImportSuccess" />

    <!-- loading 弹窗  -->
    <syncDialog ref="syncDialogRef" @timerOver=" timerOver "></syncDialog>
</template>

<style lang="less" scoped>

.AIdigitalHumanMassProduction{
    height: 100%;
    width: 100%;

    display: flex;
    gap: 20px;

    :deep(.ss-tabs-nav) {
        margin-bottom: 0;
    }


    .content_left{
        // background-color: rgba(255, 192, 203, 0.212);
        flex: 1;
        min-width: 890px;
        padding: 12px;

        .content_left_list_box{
            width: 100%;
            height: 100%;
            display: flex;
            flex-direction: column;

            overflow: hidden;

            // overflow-y: auto;
            // &::-webkit-scrollbar {
            //     width: 5px;
            //     /* 滚动条的宽度 */
            //     height: 10px;
            //     /* 滚动条的高度，垂直滚动条可能用得上 */
            //     }

            //     &::-webkit-scrollbar-thumb {
            //     background: #c4c4c4;
            //     /* 滑块的背景颜色 */
            //     border-radius: 10px;
            // /* 滑块的圆角 */
            // }

            .content_left_list_scroll_box{
                width: 100%;
                height: 100%;
                flex: 1;
                padding-bottom: 10px;

            overflow-y: auto;
            &::-webkit-scrollbar {
                width: 5px;
                /* 滚动条的宽度 */
                height: 10px;
                /* 滚动条的高度，垂直滚动条可能用得上 */
                }

                &::-webkit-scrollbar-thumb {
                background: #c4c4c4;
                /* 滑块的背景颜色 */
                border-radius: 10px;
            /* 滑块的圆角 */
            }
            // 每一个卡片
            .content_left_list_item{
                background-color: #fff;
                padding: 15px;
                border-radius: 10px;
                margin-bottom: 20px;

                box-shadow: 0 0 12px rgba(0, 0, 0, 0.06); /* 透明度调低更柔和 */


                .cart_top{
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    padding-bottom: 15px;
                    // background-color: rgb(63, 185, 233);
                    border-radius: 12px 12px 0 0;

                    
                    .cart_top_left{
                        display: flex;
                        align-items: center;
                        .cart_title{
                            font-weight: bold;
                            width: 150px;
                        }
                        .cart_top_left_right{
                            display: flex;
                            align-items: center;
                            gap: 10px;
    
                            .human_audio_type{
                                color: #222;
                                padding: 5px;
                                border-radius: 6px;
                                margin-left: 5px;
                                font-size: 14px;
                                cursor: pointer;
                                position: relative;
    
                                &::after{
                                        content: '';
                                        height: 2px;
                                        width: 100%;
                                        position: absolute;
                                        bottom: 0;
                                        left: 0;
                                        background-color: transparent;
    
                                    }
                                &:hover{
                                    color: var(--ss-primary-color-hover);
                                }
                                &.active_cls {
                                    color: var(--ss-primary-color);
    
                                    &::after{
                                        background-color: var(--ss-primary-color);
                                    }
                                }
                      
                            }
                        }
                    }

                    .cart_top_right{
                        display: flex;
                        align-items: center;
                        gap: 10px;
                    }


                }
                .cart_content{
                    width: 100%;
                    height: 230px;
                    // background-color: #7be0e046;
                    border-radius: 0 0 12px 12px;
                    display: flex;
                    gap: 10px;

      

                    .cart_content_center{
                        flex: 1;
                        min-width: 440px;

                        .text_controls{
                            display: flex;
                            align-items: center;
                            gap: 20px;
                            padding-left: 7px;
                            :deep(.ss-btn-link){
                                padding: 0;
                            }
                        }

                        .audio_type_content{
                            height: 100%;
                            width: 100%;
                    // 选择音频容器公共样式
                    .select_voice_style {
                        height: 100%;
                        width: 100%;
                        border-radius: 8px;
                        border: 1px solid #ebebeb;
                        display: flex;

                        &:hover {
                            border-color: var(--ss-primary-color-hover);
                            color: var(--ss-primary-color-hover);
                        }
                        }

                        // 没有音频的样式
                        .select_voice {
                        cursor: pointer;
                        flex-direction: column;
                        align-items: center;
                        justify-content: center;
                        color: #666666;
                        transition: all 0.3s;

                        .FolderOutlined {
                            font-size: 30px;
                        }
                        }

                                // 选择了音频的样式
        .have_voice {
          // flex-direction: column;
          // align-items: center;
          // justify-content: space-between;
          padding: 15px;
          position: relative;
          transition: all 0.3s;

          .voice_icon {
            color: #666666;
            cursor: pointer;
            font-size: 60px;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);

            &:hover {
              color: var(--ss-primary-color-hover);
            }
          }

          .del_icon {
            color: #666666;
            cursor: pointer;
            position: absolute;
            right: 10px;
            top: 10px;
            font-size: 23px;

            &:hover {
              color: var(--ss-error-color);
            }
          }

          audio {
            width: calc(100% - 30px);
            position: absolute;
            bottom: 15px;
            left: 15px;
          }
        }

                }

            }

                    .cart_content_left {
                        min-width: 140px;
                        height: 100%;
                        display: flex;
                        flex-direction: column;
                        border: 1px solid #ccc;
                        background-color: #000;
                        border-radius: 10px;
                        overflow: hidden;

                        cursor: pointer;
                        .diahuman_video{
                            position: relative;
                            height: calc(100% - 30px);
                            width: 100%;

                            video, img{
                                width: 138px;
                                height: 198px;
                            }
                            &:hover {
                                border-color: var(--ss-primary-color-hover);
                                .EyeOutlined {
                                    opacity: 1;
                                }
                                &::after {
                                    opacity: 1;
                                }

                            }

                            &::after {
                            content: "";
                            position: absolute;
                            left: 0;
                            top: 0;
                            width: 100%;
                            height: 100%;
                            background: #0000004b;
                            opacity: 0;
                            transition: all 0.3s;
                            }
                            .EyeOutlined {
                                position: absolute;
                                left: 50%;
                                top: 50%;
                                transform: translate(-50%, -50%);
                                transition: all 0.3s;
                                opacity: 0;
                                font-size: 30px;
                                color: #fff;
                                z-index: 2;

                                &:hover {
                                    color: var(--ss-primary-color-hover);
                                }
                            }
                        }

                        img{
                            object-fit: contain;
                        }

                        .change_aihuman{
                            cursor: pointer;
                            line-height: 30px;
                            text-align: center;
                            color: #fff;
                            background-color: var(--ss-primary-color);
                            // border-radius: 0 0 10px 10px;
                        }

                        .add_ai_human{
                            height: 100%;
                            display: flex;
                            flex-direction: column;
                            justify-content: center;
                            align-items: center;
                            gap: 10px;
                            .add_icon{
                                font-size: 26px;
                                color: #fff;
                            }
                            .add_tips{
                                font-size: 14px;
                                color: #fff;
                            }
                        }
                    }

                    .cart_content_right{
                        min-width: 300px;
                        height: 100%;
                        display: flex;
                        flex-direction: column;
                        gap: 5px;
                        padding: 10px;
                        border-radius: 10px;
                        box-shadow: 0 0 12px rgba(0, 0, 0, 0.06); /* 透明度调低更柔和 */
                        .cart_content_voice{
                            display: flex;
                            justify-content: space-between;
                            align-items: center;
                            gap: 5px;
                            .voice_name{
                                flex: 1;
                            }
                            img {
                                width: 32px;
                                height: 32px;
                                object-fit: contain;
                            }
                        }

                        .cart_content_voice_config{
                            // background-color: #8cfce0;
                            flex: 1;
                            display: flex;
                            flex-direction: column;
                            justify-content: space-between;
                            transform: translateY(10px);
                            .voice_config_item{
                                display: flex;
                                flex-direction: column;
                                .config_subtitle {
                                    margin: 0;
                                    font-weight: bold;
                                }
                                .slider_box{
                                    display: flex;
                                    align-items: center;
                                    .slider {
                                    flex: 1;
                                    }
                                }
                            }
                        }
                    }

                }
            }

            }

            // 顶部按钮
            .top_controls{
                margin-bottom: 20px;
                display: flex;
                align-items: center;
                justify-content: space-between;
                background-color: #fff;
                padding: 12px;
                border-radius: 10px;

                .top_controls_right{
                    display: flex;
                    align-items: center;
                    gap: 20px;
                }
            }

            // 新增按钮
            .add_item_box{
                width: 100%;
                .btn {
                    border-color: var(--ss-primary-color-hover);
                }
            }
        }
    }

    .content_right{
        background-color: rgba(255, 0, 0, 0.13);
        width: 30%;
        min-width: 200px;
    }
}
</style>